package com.pattern.creational_pattern.builder_pattern;

/**
 * @Description PRODUCT ROLE in Builder pattern.
 * @Author Ping
 * @Date 2022/3/20 22:38
 **/
public class Meal {
    /**
     * product consists of two parts, ie, food and drink .
     */
    private String food ;
    private String drink ;

    public Meal() {
    }

    /**
     * if these two attributes are necessary, it would be better to provide a constructor with two
     * related parameters.
     * @param food
     * @param drink
     */
    public Meal(String food, String drink) {
        this.food = food;
        this.drink = drink;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public String getDrink() {
        return drink;
    }

    public void setDrink(String drink) {
        this.drink = drink;
    }
    @Override
    public String toString() {
        return "MEAL: (" + this.food + " + " + this.drink + ")" ;
    }

    /**
     * provide a builder for the meal(Complex obj)
     */
    static class MealBuilder {
        /**
         * meal's attrs, as builder's attrs
         */
        protected String food ;
        protected String drink ;

        public MealBuilder() {
        }

        /**
         * chain programming could be used, since the return was current object
         * Chain, stream programming,
         * List lst = new ArrayList<>() ;
         * lst.stream()
         *         .forEach(e ->
         *         {}) ;
         * functional programming.
         * @return
         */
        public MealBuilder buildFood() {
            return this ;
        }
        public   MealBuilder buildDrink() {
            return this ;
        }
        public Meal buildMeal() {
            // construct a meal
            Meal meal = new Meal() ;
            // do null-checking.
            if (this.drink != null) {
                meal.setDrink(this.drink);
            }
            if (this.food != null) {
                meal.setFood(this.food);
            }
            return meal ;
        }

        /**
         * Also, provide a construct method here.
         * @return
         */
        public Meal build() {
            return this.buildDrink()
                        .buildFood()
                          .buildMeal() ;
        }
    }


    public static void main(String args[]) {
        Meal meal = new Meal.MealBuilder().build();

    }
}
